#ifndef FatStructs_h
#define FatStructs_h

//ESTRUCTURAS FAT32

typedef struct fat32BootSector
{
	uint8_t  jmpToBootCode[3];
  	char     oemName[8];
    uint16_t bytesPerSector;
    uint8_t  sectorsPerCluster;
    uint16_t reservedSectorCount;
    uint8_t  fatCount;
    uint16_t rootDirEntryCount;
    uint16_t totalSectors16;
    uint8_t  mediaType;
    uint16_t sectorsPerFat16;
    uint16_t sectorsPerTrtack;
    uint16_t headCount;
    uint32_t hidddenSectors;
    uint32_t totalSectors32;
    uint32_t sectorsPerFat32;
    uint16_t fat32Flags;
    uint16_t fat32Version;
    uint32_t fat32RootCluster;
    uint16_t fat32FSInfo;
    uint16_t fat32BackBootBlock;
    uint8_t  fat32Reserved[12];
    uint8_t  driveNumber;
    uint8_t  reserved1;
    uint8_t  bootSignature;
    uint32_t volumeSerialNumber;
    char     volumeLabel[11];
    char     fileSystemType[8];
    uint8_t  bootCode[420];
    uint8_t  bootSectorSig0;
    uint8_t  bootSectorSig1;
}__attribute__((__packed__));
typedef struct fat32BootSector fbs_t;


struct directoryEntry
{
  uint8_t  name[11];
  uint8_t  attributes;
  uint8_t  reservedNT;
  uint8_t  creationTimeTenths;
  uint16_t creationTime;
  uint16_t creationDate;
  uint16_t lastAccessDate;
  uint16_t firstClusterHigh;
  uint16_t lastWriteTime;
  uint16_t lastWriteDate;
  uint16_t firstClusterLow;
  uint32_t fileSize;
}__attribute__((__packed__));
typedef struct directoryEntry dir_t;


struct LongNameDirectoryEntry
{
	uint8_t ordinal;
	uint8_t Name1[10];
	uint8_t attributes;
	uint8_t type;
	uint8_t checksum;
	uint8_t Name2[12];
	uint16_t LegacyClusLO;
	uint8_t Name3[4];
}__attribute__((__packed__));
typedef struct LongNameDirectoryEntry dirL_t;



//MASCARAS PARA VALIDACION DE CLUSTERS

uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; //PRIMER VALOR DE EOC VALIDO (ES EOC SI ES MAYOR)
uint32_t const FAT32FIRST_VALID = 0x00000002; //PRIMER VALOR DE CLUSTER VALIDO
uint32_t const FAT32LAST_VALID = 0X0FFFFFF5; //ULTIMO VALOR DE CLUSTER VALIDO


//MASCARAS PARA NOMBRES DE DIRECTORY ENTRIES

uint8_t const DIR_NAME_PADDING = 0X20; // PADDING QUE SEPARA NOMBRE DE EXTENSION, PARA SER IGNORADO AL CONVERTIR EL NOMBRE A UN STRING
uint8_t const DIR_NAME_DELETED = 0XE5; // PARA POSICION [0], NO EXISTE ENTRY, BORRADA
uint8_t const DIR_NAME_FREE = 0X00; // PARA POSICION [0], NO EXISTE ENTRY Y NO SIGUE NINGUN OTRO


//ATRIBUTOS RELEVANTES DE DIRECTORY ENTRIES

uint8_t const DIR_ATT_READ_ONLY = 0X01;
uint8_t const DIR_ATT_HIDDEN = 0X02;
uint8_t const DIR_ATT_SYSTEM = 0X04;
uint8_t const DIR_ATT_DIRECTORY = 0X10;


//FUNCIONES PARA TESTEAR TIPO DE ENTRY/ARCHIVO

static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {return (dir->attributes & 0X3F) == 0X0F;}
static inline uint8_t DIR_IS_FILE(const dir_t* dir) {return (dir->attributes & (0X08 | 0X10)) == 0;}
static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {return (dir->attributes & (0X08 | 0X10)) == DIR_ATT_DIRECTORY;}


#endif  // FatStructs_h
